﻿/*!
 *  @brief     样式管理器
 *  @details   提供对内置样式的管理，支持从指定配置目录下读取扩展的样式文件
 *             样式分为内置和动态加载两种方式获取：
 *                   1.内置：以qrc资源文件形式编译至程序内部，若动态加载失败时，以内置的主题为默认主题；
 *                   2.动态加载：以主题为单位存放于config/schemes目录下，子目录包括img、css等文件夹；
 *             不管是内置还是动态加载的形式，均会在[设置]-[样式]菜单中创建触发按钮。
 *
 *             以dark目录为例：
 *             [+]dark:主题名
 *                [+]img：存放当前主题所需要的图片信息【可选】；
 *                [+]qss：存放主题的qss信息【必须】；
 *                   [-]style.qss：主题样式文件，系统会根据此名称加载主题，找不到此文件即失败【必须】；
 *  @author    wey
 *  @version   1.0
 *  @date      2018.09.15
 *  @warning
 *  @copyright NanJing RenGu.
 *  @note 2018.12.13:wey:增加从置顶路径下加载样式文件;
 *
    QString sttStylePath = QString("E:/YinzgCode/ViewFrame-qt/bin/x64/Debug/styles/white");
    Singleton<Common::StyleHandler>::instance()->dynamicLoadStyle(sttStylePath);

    QString sttStylePath2 = QString("E:/YinzgCode/ViewFrame-qt/bin/x64/Debug/styles/black");
    Singleton<Common::StyleHandler>::instance()->dynamicLoadStyle(sttStylePath2);

    Singleton<Common::StyleHandler>::instance()->switchStyle(1);
 *
 */
#ifndef SYSTESTYLE_H
#define SYSTESTYLE_H

#include "common_global.h"

#include <QObject>
#include <QList>

class QAction;

namespace Common{

/*!
 *  @brief 自定义样式信息描述
 *  @details
 */
class COMMONSHARED_EXPORT CustomStyle{

public:
    /*!
     *  @brief 自定义样式类枚举
     *  @details 每添加一种style，即添加一个字段
     */
    enum CustomStyleClass
    {

    };

    CustomStyle()
    {

    }

    CustomStyle(QString name, QString path, bool selected = false)
        : name(name)
        , path(path)
        , selected(selected)
        , stype(STYLE_SHEET)
    {

    }

    CustomStyle(QString name, CustomStyleClass clazz, bool selected = false)
        : name(name)
        , clazz(clazz)
        , selected(selected)
        , stype(STYLE_CUSTOMSTYLE)
    {

    }

    /**
     * @brief 样式表类型
     */
    enum StyleType
    {
        STYLE_SHEET,            /*!< 样式表文件 */
        STYLE_CUSTOMSTYLE       /*!< 自定义样式类 */
    };

    /**
     * @brief getStyleName 获取样式表名称
     * @return
     */
    QString getStyleName()const{return this->name;}

    /**
     * @brief getStyleType 获取样式表类型
     * @return
     */
    StyleType getStyleType(){return this->stype;}

    /**
     * @brief getClazz 获取自定义样式表
     * @return
     */
    CustomStyleClass getClazz(){return this->clazz;}

    /**
     * @brief getStylePath 获取样式表类型
     * @return
     */
    QString getStylePath()const{return this->path;}

    /**
     * @brief isSelected
     * @return
     */
    bool isSelected()const{return this->selected;}

    /**
     * @brief setAction 设置菜单动作
     * @param action
     */
    void setAction( QAction * action){this->action = action;}

    /**
     * @brief getAction
     * @return
     */
    QAction * getAction(){return this->action;}

private:
    QString name;           /*!< 样式名 */
    StyleType stype;        /*!< 样式类型 */
    CustomStyleClass clazz; /*!< 自定义样式类型 */
    QString path;           /*!< 样式保存路径，可为本地路径，也可为资源文件中路径 */
    bool selected;          /*!< 是否被选中显示 */
    QAction * action;       /*!< 工具栏对应按钮 */
};

typedef QList<CustomStyle *> StylePtrList;

class StyleHandlerPrivate;
class COMMONSHARED_EXPORT StyleHandler : public QObject
{
    Q_OBJECT
    Q_DECLARE_PRIVATE(StyleHandler)

public:
    explicit StyleHandler();
    ~StyleHandler();

public:
    /**
     * @brief addStyle 添加样式表
     * @param style
     */
    void addStyle(CustomStyle * style);

    /*!
     * @brief   从指定的路径中加载动态的样式属性
     * @param[in] stylePath 待加载的样式路径
     */
    bool dynamicLoadStyle(QString stylePath);

    /**
     * @brief size 获取样式表个数
     * @return
     */
    int size();

    /**
     * @brief styles 获取样式表列表
     * @return
     */
    StylePtrList styles();

    /**
     * @brief switchStyle 切换样式表
     * @param index
     */
    bool switchStyle(int index = 0);

    /**
     * @brief currentStyle 获取当前的样式表
     * @return
     */
    CustomStyle *currentStyle();

    /**
     * @brief findStyle 根据样式表名称查看样式表名称
     * @param styleName
     * @return
     */
    CustomStyle * findStyle(QString styleName);

private:
    /**
     * @brief isValidStyleDir
     * @param singleStyleDir
     * @return
     */
    bool isValidStyleDir(QString singleStyleDir);

    /**
     * @brief getStyleFile
     * @param styleRootPath
     * @return
     */
    inline QString getStyleFile(QString styleRootPath);

private:
    StyleHandlerPrivate * d_ptr;
};

} //namespace Common

#endif // SYSTESTYLE_H
